package version_3;

/**
 * @author 王子铮 11923040205
 * @version 3.0
 */

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.Line;
import javafx.scene.text.Font;
import javafx.stage.Stage;

import java.awt.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * 本程序未按照题目所提示的存储方法，玩家标记改用int型数据存储，X玩家3，O玩家5。这样可以更便捷地判断胜负。
 * 这个文件是主程序，应该从这里启动
 * 棋盘数据保存在map数组中，判定时读取map数组的内容
 * map数组中的值：3代表X，5代表O，0代表空白
 * turn代表走棋的步骤，turn为0代表已经决出胜负或者平局，不需要任何一方走棋
 * step代表走的步数，步数达到9仍未决出胜负即为平局
 */
public class TicTacToe extends Application {
    // O玩家先走棋
    public int turn=3;
    // 初始化步数为0
    private int step=0;
    // 定义map数组
    private final int[][] map=new int[3][3];
    // 显示实时信息的标签
    private final Label status = new Label("欢迎！ 游戏开始!");

    public static void main(String[] args) {
        launch(args);
    }

    /**
     * 初始化程序，用于重新开始时的重新初始化向量
     */
    public void init_game(){
        // O玩家先走棋
        turn=3;
        // 初始化步数为0
        step=0;
        // 定义map数组
        for (int i=0;i<3;i++){
            for (int j=0;j<3;j++){
                map[i][j]=0;
            }
        }
        // 显示实时信息的标签
        status.setText("新的游戏开始!");
    }

    @Override
    public void start(Stage primaryStage) {

        status.setFont(Font.font(20));

        Cell[][] cells=new Cell[3][3];
        // 创建Pane存放Cell
        GridPane pane = new GridPane();
        //创建9个Cell
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++){
                //pane.add(new Cell(i,j), i, j);
                cells[i][j]=new Cell(i,j);
                pane.add(cells[i][j], i, j);
            }

        // 重新开始按钮
        Button restart=new Button("开始新的游戏");
        restart.setPrefWidth(450);
        restart.setFont(Font.font(20));
        // 重新开始
        restart.setOnAction(event -> {
            // 清空原面板中的内容
            pane.getChildren().clear();
            // 创建9个Cell
            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++){
                    //pane.add(new Cell(i,j), i, j);
                    cells[i][j]=new Cell(i,j);
                    pane.add(cells[i][j], i, j);
                }
            // 初始化其它参数
            init_game();
        });

        /**
        BorderPane borderPane = new BorderPane();
        borderPane.setTop(restart);
        borderPane.setCenter(pane);
        borderPane.setBottom(status);
         */

        //设置菜单
        MenuBar menuBar=new MenuBar();

        Menu menuGame=new Menu("Game");
        MenuItem menu_restart=new MenuItem("new game");
        menuGame.getItems().addAll(menu_restart);
        Menu menuAbout=new Menu("About");
        Menu setMenu=new Menu("Set");

        //打开我的gitee仓库
        MenuItem open_gitee=new MenuItem("open my gitee");
        menuAbout.getItems().add(open_gitee);
        open_gitee.setOnAction(event -> {
            try {
                Desktop.getDesktop().browse(new URI("https://gitee.com/wang28043550225/java_homework"));
            } catch (IOException | URISyntaxException e) {
                e.printStackTrace();
            }
        });

        MenuItem set_color_red=new MenuItem("set color red");
        setMenu.getItems().addAll(set_color_red);
        //设置背景颜色
        set_color_red.setOnAction(event -> {
            pane.getChildren().clear();
            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++) {
                    cells[i][j]=new Cell(i,j);
                    cells[i][j].setColor();
                    pane.add(cells[i][j], i, j);
                }
            init_game();
            status.setText("已设置背景颜色为红色，请继续游戏！");
        });

        MenuItem menu_about=new MenuItem("about");
        menuAbout.getItems().addAll(menu_about);

        //显示信息
        menu_about.setOnAction(event -> {
            BorderPane pane1=new BorderPane();
            Stage stage2=new Stage();
            Label inf=new Label("version 3 by wzz 11923040205");
            inf.setFont(Font.font(30));
            Button close=new Button("确定");
            close.setOnAction(e -> {
                stage2.close();
            });
            //设置布局
            pane1.setTop(inf);
            pane1.setBottom(close);
            stage2.setScene(new Scene(pane1,500,100));
            stage2.setTitle("project2 version 3");
            stage2.show();
        });

        //设置监听
        menu_restart.setOnAction(event -> {
            // 清空原面板中的内容
            pane.getChildren().clear();
            // 创建9个Cell
            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                    pane.add(new Cell(i,j), j, i);
            // 初始化其它参数
            init_game();
        });

        menuBar.getMenus().addAll(menuGame,setMenu,menuAbout);


        //设置主界面布局
        VBox vBox=new VBox();
        vBox.getChildren().addAll(menuBar,restart,pane,status);


        Scene scene = new Scene(vBox, 450, 550);
        primaryStage.setTitle("井字游戏_wzz");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * 每个Cell为一个小格
     * 棋盘数据保存在map数组中，判定时读取map数组的内容
     * map数组中的值：3代表X，5代表O，0代表空白
     * turn代表走棋的步骤，turn为0代表已经决出胜负或者平局，不需要任何一方走棋
     * step代表走的步数，步数达到9仍未决出胜负即为平局
     */
    public class Cell extends Pane{
        private final int row;
        private final int column;
        public Cell(int i,int j) {
            setStyle("-fx-border-color: #000000");
            this.setPrefSize(150, 150);
            this.setOnMouseClicked(e -> handleMouseClick());
            this.row=i;
            this.column=j;
        }

        //设置背景颜色为红色
        public void setColor(){
            setStyle("-fx-background-color: #ea4949");
        }

        /**
         * 接受信息后在对应位置画图
         * 更新map数组中的值
         */
        public void setToken(int token) {
            if (token == 3) {
                map[row][column]=3;
                step++;
                Line line1 = new Line(10, 10,
                        this.getWidth() - 10, this.getHeight() - 10);
                line1.endXProperty().bind(this.widthProperty().subtract(10));
                line1.endYProperty().bind(this.heightProperty().subtract(10));
                Line line2 = new Line(10, this.getHeight() - 10,
                        this.getWidth() - 10, 10);
                line2.startYProperty().bind(
                        this.heightProperty().subtract(10));
                line2.endXProperty().bind(this.widthProperty().subtract(10));

                // 添加到Pane中
                this.getChildren().addAll(line1, line2);
            }
            else if (token == 5) {
                map[row][column]=5;
                step++;
                Ellipse ellipse = new Ellipse(this.getWidth() / 2,
                        this.getHeight() / 2, this.getWidth() / 2 - 10,
                        this.getHeight() / 2 - 10);
                ellipse.centerXProperty().bind(
                        this.widthProperty().divide(2));
                ellipse.centerYProperty().bind(
                        this.heightProperty().divide(2));
                ellipse.radiusXProperty().bind(
                        this.widthProperty().divide(2).subtract(10));
                ellipse.radiusYProperty().bind(
                        this.heightProperty().divide(2).subtract(10));
                ellipse.setStroke(Color.BLACK);
                ellipse.setFill(Color.WHITE);

                getChildren().add(ellipse);
            }
        }

        /**
         * 鼠标点击的响应函数
         */
        private void handleMouseClick() {
            //转换玩家走棋顺序
            if (turn==3){
                turn=5;
                status.setText("玩家 X 行动");
            } else if (turn==5){
                turn=3;
                status.setText("玩家 O 行动");
            }

            // 判断该位置是否已经存在棋子
            if (Main.isFilled(map,row,column)){
                status.setText("该位置已有棋子！");
                if (turn==3){
                    turn=5;
                } else if (turn==5){
                    turn=3;
                }
            } else if (turn==3){
                setToken(3);
            } else if (turn==5){
                setToken(5);
            }

            // 判断游戏是否可以结束，如果结束，将turn变为0，阻止玩家的进一步操作
            if (Main.ifWin(map) == 1) {
                status.setText("玩家 X 胜利，游戏结束！");
                turn=0;
            } else if (Main.ifWin(map) == 2) {
                status.setText("玩家 O 胜利，游戏结束！");
                turn=0;
            } else if (Main.stepOver(step)) {
                status.setText("平局！ 游戏结束！");
                turn=0;
            }
        }
        }
    }


